package com.simple_frame.exceptionHandle;

import com.simple_frame.utils.Result;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestControllerAdvice
public class GlobeExceptionHandle {
    
    @ExceptionHandler(Exception.class)
    public Result<String> exceptionHandle(Exception e) {
        log.error(e.toString());
        return Result.fail("服务器异常");
    }
    
    /**
     * 捕获SpringSecurity的用户不存在异常
     */
    @ExceptionHandler(InternalAuthenticationServiceException.class)
    public Result<String> InternalAuthenticationServiceExceptionHandle(InternalAuthenticationServiceException e) {
        log.error(e.toString());
        return Result.fail("用户不存在");
    }
    
    //处理请求参数格式错误 @RequestBody上@Valid校验失败后抛出的异常是MethodArgumentNotValidException异常。
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<String> handleValidationExceptions(MethodArgumentNotValidException ex) {
        List<String> errors = ex.getBindingResult().getFieldErrors().stream()
                .map(DefaultMessageSourceResolvable::getDefaultMessage)
                .collect(Collectors.toList());
        String errorMessage = String.join(", ", errors);
        log.error(ex.toString());
        return Result.fail(errorMessage, 400);
    }
    
    //处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是javax.validation.ConstraintViolationException
    @ExceptionHandler(ConstraintViolationException.class)
    public Result<String> handleConstraintViolationException(ConstraintViolationException ex) {
        List<String> errors = ex.getConstraintViolations().stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.toList());
        String errorMessage = String.join(", ", errors);
        log.error(ex.toString());
        return Result.fail(errorMessage, 400);
    }
    
}
